package br.com.sgmf.dao;

import java.util.Date;
import java.util.List;

import javax.persistence.EntityManager;
import javax.persistence.PersistenceContext;
import javax.persistence.criteria.CriteriaBuilder;
import javax.persistence.criteria.CriteriaQuery;
import javax.persistence.criteria.Expression;
import javax.persistence.criteria.Root;

import org.apache.commons.lang3.StringUtils;
import org.springframework.stereotype.Repository;
import org.springframework.transaction.annotation.Transactional;

import br.com.sgmf.model.HistoricoVeiculo;
import br.com.sgmf.model.Veiculo;

@Repository
public class VeiculoDAO {

	@PersistenceContext
	private EntityManager manager;

	@Transactional
	public void save(Veiculo veiculo) {
		manager.persist(veiculo);
	}

	@Transactional
	public void update(Veiculo veiculo) {
		manager.merge(veiculo);
	}

	@Transactional
	public void delete(Veiculo veiculo) {
		veiculo = manager.merge(veiculo);
		manager.remove(veiculo);
	}

	@Transactional(readOnly = true)
	public Veiculo findById(Integer id) {
		return manager.find(Veiculo.class, id);
	}

	@SuppressWarnings("unchecked")
	@Transactional(readOnly = true)
	public List<Veiculo> findAll() {
		return manager.createNamedQuery("Veiculo.findAll").getResultList();
	}

	@SuppressWarnings("unchecked")
	@Transactional(readOnly = true)
	public List<Veiculo> findByPlaca(String placa) {
		return manager.createNamedQuery("Veiculo.findByPlaca")
				.setParameter("placa", "%" + placa + "%").getResultList();
	}

	@Transactional(readOnly = true)
	public List<HistoricoVeiculo> findBetweenDate(Date inicio, Date fim,
			String placaVeiculo) {
		CriteriaBuilder builder = manager.getCriteriaBuilder();
		CriteriaQuery<HistoricoVeiculo> query = builder
				.createQuery(HistoricoVeiculo.class);
		Root<HistoricoVeiculo> historicoVeiculo = query
				.from(HistoricoVeiculo.class);

		if (inicio != null || fim != null) {
			Expression<Date> data = historicoVeiculo.get("data");
			if (inicio != null && fim != null) {
				query.where(builder.between(data, inicio, fim));
			} else if (inicio != null && fim == null) {
				query.where(builder.greaterThanOrEqualTo(data, inicio));
			} else if (fim != null && inicio == null) {
				query.where(builder.lessThanOrEqualTo(data, fim));
			}
		}

		if (StringUtils.isNotBlank(placaVeiculo)) {
			Root<Veiculo> veiculo = query.from(Veiculo.class);
			Expression<String> placa = veiculo.get("placa");
			query.where(builder.equal(placa, placaVeiculo));
		}

		return manager.createQuery(query).getResultList();
	}

}
